function json2map(json) {
	var players = new Array();
	for (var i = 0; i < json.players.length; ++i) {
		var player = json.players[i];
		players.push(json2player(player));
	}
	var regions = new Array();
	for (var i = 0; i < json.regions.length; ++i) {
		var region = json.regions[i];
		regions.push(json2region(region));
	}
	var areas = new Array();
	for (var i = 0; i < json.areas.length; ++i) {
		var area = json.areas[i];
		areas.push(json2area(area));
	}
	var links = new Array();
	for (var i = 0; i < json.links.length; ++i) {
		var link = json.links[i];
		links.push(json2link(link));
	}

	return new Map(players, regions, areas, links);
}
function json2player(json) {
	return new Player(json.id, json.name, json.color, json.areas);
}
function json2region(json) {
	return new Region(json.id, json.name, json.bonus, json.areas);
}
function json2area(json) {
	var region = "";
	var shape = (typeof json.shape === 'string') ? json.shape : "-10, -10, 10, -10, 10, 10, -10, 10";

	return new Area(json.id, json.name, json.region, json.x, json.y, "img", shape, json.links, json.owner, json.force);
}
function json2link(json) {
	return new Link(json.id, json.start, json.end, json.cost);
}

function map2json(map) {
	var json = new Object();

	json.players = new Array();
	for (var i = 0; i < map.players.length; ++i) {
		var player = map.players[i];
		json.players.push(player2json(player));
	}

	json.areas = new Array();
	for (var i = 0; i < map.areas.length; ++i) {
		var area = map.areas[i];
		json.areas.push(area2json(area));
	}

	json.links = new Array();
	for (var i = 0; i < map.links.length; ++i) {
		var link = map.links[i];
		json.links.push(link2json(link));
	}

	return json;
}
function player2json(player) {
	var json = new Object();

	json.id    = player.id;
	json.name  = player.name;
	json.areas = player.areas;

	return json;
}
function area2json(area) {
	var json = new Object();

	json.id    = area.id;
	json.name  = area.name;
	json.x     = area.x;
	json.y     = area.y;
	json.links = area.links;
	json.owner = area.owner;
	json.force = force;

	return json;
}
function link2json(link) {
	var json = new Object();

	json.id    = link.id;
	json.start = link.start;
	json.end   = link.end;
	json.cost  = link.cost;

	return json;
}

function MapManager(map) {
	this.map = map;

	this.createArea = function(id, name, region, x, y, img, shape, links, owner, force) {
		var area = new Area(id, name, region, x, y, img, shape, links, owner, force);

		this.map.addArea(area);
		this.map.getPlayer(owner).addArea(area);
		this.map.getRegion(region).addArea(area);
	}
	this.createLink = function(id, start, end, cost) {
		var link = new Link(id, start, end, cost);

		this.map.addLink(link);
		this.map.getAreaById(start).addLink(link);
		this.map.getAreaById(end).addLink(link);
	}
}

function Map(players, regions, areas, links) {
	this.players   = new Array();
	this.addPlayer = function(player) { this.players.push(player); }
	this.delPlayer = function(player) { this.players.del(player); }
	this.getPlayer = function(n)      { return this.players[n]; }
	this.getPlayerById = function(id) {
		for (var i = 0; i < this.players.length; ++i) {
			var player = this.players[i];
			if (player.id == id) return player;
		}
		return 0;
	}
	this.clearPlayers = function() { this.players.splice(0, this.players.length); }

	if (players) {
		for (var i = 0; i < players.length; ++i) {
			var player = players[i];
			this.addPlayer(player);
		}
	}

	this.regions = new Array();
	this.addRegion = function(region) { this.regions.push(region); }
	this.delRegion = function(region) { this.regions.del(region); }
	this.getRegion = function(n) { return this.regions[n]; }
	this.getRegionById = function(id) {
		for (var i = 0; i < this.regions.length; ++i) {
			var region = this.regions[i];
			if (region.id == id) return region;
		}
		return 0;
	}
	this.clearRegions = function() { this.regions.splice(0, this.regions.length); }

	this.searchRegionsByName = function(name) {
		var regions = new Array();
		for (var i = 0; i < this.regions.length; ++i) {
			var region = this.regions[i];
			if (region.name == name) regions.push(region);
		}
		return regions;
	}

	this.areas   = new Array();
	this.addArea = function(area) { this.areas.push(area); }
	this.delArea = function(area) { this.areas.del(area); }
	this.getArea = function(n)      { return this.areas[n]; }
	this.getAreaById = function(id) {
		for (var i = 0; i < this.areas.length; ++i) {
			var area = this.areas[i];
			if (area.id == id) return area;
		}
		return 0;
	}
	this.clearAreas = function() { this.areas.splice(0, this.areas.length); }

	this.searchAreasByName = function(name) {
		var areas = new Array();
		for (var i = 0; i < this.areas.length; ++i) {
			var area = this.areas[i];
			if (area.name == name) areas.push(area);
		}
		return areas;
	}
	this.searchAreasByOwner = function(owner) {
		var areas = new Array();
		for (var i = 0; i < this.areas.length; ++i) {
			var area = this.areas[i];
			if (area.owner == owner) areas.push(area);
		}
		return areas;
	}

	if (areas) {
		for (var i = 0; i < areas.length; ++i) {
			var area = areas[i];
			this.addArea(area);
		}
	}

	this.links   = new Array();
	this.addLink = function(link) { this.links.push(link); }
	this.delLink = function(link) { this.links.del(link); }
	this.getLink = function(n)    { return this.links[n]; }
	this.getLinkById = function(id) {
		for (var i = 0; i < this.links.length; ++i) {
			var link = this.links[i];
			if (link.id == id) return link;
		}
		return 0;
	}
	this.getLinksFromArea = function(area) {
		var links = new Array();
		for (var i = 0; i < this.links.length; ++i) {
			var link = this.links[i];
			if (link.start == area) links.push(link);
		}
		return links;
	}
	this.clearLinks = function() { this.links.splice(0, this.links.length); }

	if (links) {
		for (var i = 0; i < links.length; ++i) {
			var link = links[i];
			this.addLink(link);
		}
	}

	this.toString = function() { return "[Map]"; }
}

function Player(id, name, color, areas) {
	this.id      = id;
	this.name    = name;
	this.color   = color;
	this.areas   = new Array();

	this.addArea = function(area) { this.areas.push(area); }
	this.delArea = function(area) { this.areas.del(area); }

	if (areas) {
		for (var i = 0; i < areas.length; ++i) {
			var area = areas[i];
			this.addArea(area);
		}
	}

	this.toString = function() { return "[Player '"+ this.id +"' '"+ this.name +"']"; }
}

function Region(id, name, bonus, areas) {
	this.id = id;
	this.name = name;
	this.bonus = bonus;
	this.areas = new Array();

	this.addArea = function(area) { this.areas.push(area); }
	this.delArea = function(area) { this.areas.del(area); }

	if (areas) {
		for (var i = 0; i < areas.length; ++i) {
			var area = areas[i];
			this.addArea(area);
		}
	}

	this.toString = function() { return "[Region '"+ this.id +"' '"+ this.name +"' '"+ this.bonus +"']"; }
}

function Area(id, name, region, x, y, img, shape, links, owner, force) {
	this.id     = id;
	this.name   = name;
	this.region = region;
	this.x      = x;
	this.y      = y;
	this.img    = img;
	this.shape  = shape;
	this.links  = new Array();
	this.owner  = owner;
	this.force  = force;

	this.addLink = function(link) { this.links.push(link); }
	this.delLink = function(link) { this.links.del(link); }

	if (links) {
		for (var i = 0; i < links.length; ++i) {
			var link = links[i];
			this.addLink(link);
		}
	}

	this.toString = function() { return "[Area '"+ this.id +"' '"+ this.name +"' '"+ this.owner +"']"; }
}

function Link(id, start, end, cost) {
	this.id    = id;
	this.start = start;
	this.end   = end;
	this.cost  = cost;

	this.toString = function() { return "[Link "+ this.id +"]"; }
}
